package cn.o.app.reflect;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class ReflectUtil {

	public static Class<?> getListElementClass(Class<?> listClass,
			Type genericType) {
		if (genericType == null) {
			genericType = listClass.getGenericSuperclass();
		} else {
			if (!(genericType instanceof ParameterizedType)) {
				genericType = listClass.getGenericSuperclass();
			}
		}
		if (genericType instanceof ParameterizedType) {
			Type t = ((ParameterizedType) genericType).getActualTypeArguments()[0];
			if (t instanceof Class) {
				return (Class<?>) t;
			}
			if (t instanceof ParameterizedType) {
				return (Class<?>) ((ParameterizedType) t).getRawType();
			}
		}
		return String.class;
	}

	public static Type getListElementType(Class<?> listClass, Type genericType) {
		if (genericType == null) {
			genericType = listClass.getGenericSuperclass();
		}
		if (genericType instanceof ParameterizedType) {
			return ((ParameterizedType) genericType).getActualTypeArguments()[0];
		}
		return String.class;
	}

	public static Class<?> getMapKeyClass(Class<?> mapClass, Type genericType) {
		if (genericType == null) {
			genericType = mapClass.getGenericSuperclass();
		} else {
			if (!(genericType instanceof ParameterizedType)) {
				genericType = mapClass.getGenericSuperclass();
			}
		}
		if (genericType instanceof ParameterizedType) {
			Type t = ((ParameterizedType) genericType).getActualTypeArguments()[0];
			if (t instanceof Class) {
				return (Class<?>) t;
			}
		}
		return Void.class;
	}

	public static Class<?> getMapElementClass(Class<?> mapClass,
			Type genericType) {
		if (genericType == null) {
			genericType = mapClass.getGenericSuperclass();
		} else {
			if (!(genericType instanceof ParameterizedType)) {
				genericType = mapClass.getGenericSuperclass();
			}
		}
		if (genericType instanceof ParameterizedType) {
			Type t = ((ParameterizedType) genericType).getActualTypeArguments()[1];
			if (t instanceof Class) {
				return (Class<?>) t;
			}
			if (t instanceof ParameterizedType) {
				return (Class<?>) ((ParameterizedType) t).getRawType();
			}
		}
		return String.class;
	}

	public static Type getMapElementType(Class<?> mapClass, Type genericType) {
		if (genericType == null) {
			genericType = mapClass.getGenericSuperclass();
		}
		if (genericType instanceof ParameterizedType) {
			return ((ParameterizedType) genericType).getActualTypeArguments()[1];
		}
		return String.class;
	}
}
